﻿#region Namespaces

using System;
using System.Collections;
using System.Collections.Generic;

using Vibstudio.X4NET.Test.Util;
using Vibstudio.X4NET.Xml.Linq;
using Vibstudio.X4NET.Xml.XPath;

using Microsoft.VisualStudio.TestTools.UnitTesting;

#endregion

namespace Vibstudio.X4NET.Test
{
    [TestClass]
    public class XPathTests
    {
        public TestContext TestContext { get; set; }

        [TestMethod]
        public void ExtractXPaths_Default()
        {
            const string SAMPLE_FILE_NAME = "SM2_0303_2015015.xml";
            
            XPathList expected = new XPathList(new[]
                                               {
                                                   "/Prestazione/@cod_servizio",
                                                   "/Prestazione/@cod_flusso",
                                                   "/Prestazione/IdentificativiRichiesta[1]/piva_utente[1]",
                                                   "/Prestazione/IdentificativiRichiesta[1]/piva_distr[1]",
                                                   "/Prestazione/IdentificativiRichiesta[1]/cod_prat_utente[1]",
                                                   "/Prestazione/IdentificativiRichiesta[1]/cod_prat_distr[1]",
                                                   "/Prestazione/DatiTecnici[1]/cod_pdr[1]",
                                                   "/Prestazione/data_ese[1]"
                                               });

            XPathList actual = XDocument.Load(IOHelper.ComposeSampleFilePath(SAMPLE_FILE_NAME).Path).ExtractXPaths();

            Assert.IsTrue(actual.IsMatch(expected));
        }

        [TestMethod]
        public void ExtractXPaths_WithoutDeclaractions()
        {
            const string SAMPLE_FILE_NAME = "A01_0050_Instance.xml";
            
            XPathList actual = XDocument.Load(IOHelper.ComposeSampleFilePath(SAMPLE_FILE_NAME).Path).ExtractXPaths().StripDeclarations();

            Assert.IsTrue(actual.Count == 66);
        }

        [TestMethod]
        public void ExtractXPaths_NoAttributes()
        {
            const string SAMPLE_FILE_NAME = "SM2_0303_2015015.xml";

            XPathList expected = new XPathList(new[]
                                               {
                                                   "/Prestazione/IdentificativiRichiesta[1]/piva_utente[1]",
                                                   "/Prestazione/IdentificativiRichiesta[1]/piva_distr[1]",
                                                   "/Prestazione/IdentificativiRichiesta[1]/cod_prat_utente[1]",
                                                   "/Prestazione/IdentificativiRichiesta[1]/cod_prat_distr[1]",
                                                   "/Prestazione/DatiTecnici[1]/cod_pdr[1]",
                                                   "/Prestazione/data_ese[1]"
                                               });

            XPathList actual = XDocument.Load(IOHelper.ComposeSampleFilePath(SAMPLE_FILE_NAME).Path).ExtractXPaths(true, false, false);

            Assert.IsTrue(actual.IsMatch(expected));
        }

        [TestMethod]
        public void ExtractXPaths_WithXPath1()
        {
            const string SAMPLE_FILE_NAME = "SM2_0303_2015015.xml";
            const string XPATH = "/Prestazione/IdentificativiRichiesta";

            XPathList expected = new XPathList(new[]
                                               {
                                                   "/IdentificativiRichiesta/piva_utente[1]",
                                                   "/IdentificativiRichiesta/piva_distr[1]",
                                                   "/IdentificativiRichiesta/cod_prat_utente[1]",
                                                   "/IdentificativiRichiesta/cod_prat_distr[1]",
                                               });

            XPathList actual = XDocument.Load(IOHelper.ComposeSampleFilePath(SAMPLE_FILE_NAME).Path).ExtractXPaths(true, false, false, XPATH);

            Assert.IsTrue(actual.IsMatch(expected));
        }

        [TestMethod]
        public void ExtractXPaths_WithXPath2()
        {
            const string SAMPLE_FILE_NAME = "SM2_0303_2015015_Plus2.xml";
            const string XPATH = "//@cat";

            XPathList expected = new XPathList(new[]
                                               {
                                                   "/Prestazione[1]/IdentificativiRichiesta[1]/piva_utente[1]/@cat",
                                                   "/Prestazione[1]/DatiTecnici[1]/cod_pdr[1]/@cat"
                                               });

            XPathList actual = XDocument.Load(IOHelper.ComposeSampleFilePath(SAMPLE_FILE_NAME).Path).ExtractXPaths(true, false, false, XPATH);

            Assert.IsTrue(actual.IsMatch(expected));
        }

        [TestMethod]
        public void ExtractXPaths_WithXPath3()
        {
            const string SAMPLE_FILE_NAME = "SM2_0303_2015015_Plus2.xml";
            const string XPATH = "/Prestazione/@cod_servizio";

            XPathList expected = new XPathList(new[] { XPATH });

            XPathList actual = XDocument.Load(IOHelper.ComposeSampleFilePath(SAMPLE_FILE_NAME).Path).ExtractXPaths(true, false, false, XPATH);

            Assert.IsTrue(actual.IsMatch(expected));
        }

        [TestMethod]
        public void TagName1()
        {
            const string XPATH = "/Prestazione/ServizioEnergetico[1]/AnagraficaBeneficiario[1]/cognome[1]";
            const string expected = "cognome";

            string actual = XPathExtensions.TagName(XPATH);
            Assert.AreEqual(expected, actual);
        }

        [TestMethod]
        public void TagName2()
        {
            const string XPATH = "/Prestazione/ServizioEnergetico[1]/AnagraficaBeneficiario[1]/cognome[1]/text()";
            const string expected = "cognome";

            string actual = XPathExtensions.TagName(XPATH);
            Assert.AreEqual(expected, actual);
        }

        [TestMethod]
        public void TagName3()
        {
            const string XPATH = "/Prestazione/ServizioEnergetico/AnagraficaBeneficiario/cognome";
            const string expected = "cognome";

            string actual = XPathExtensions.TagName(XPATH);
            Assert.AreEqual(expected, actual);
        }

        [TestMethod]
        public void TagName4()
        {
            const string XPATH = "/Prestazione/ServizioEnergetico/AnagraficaBeneficiario/cognome/text()";
            const string expected = "cognome";

            string actual = XPathExtensions.TagName(XPATH);
            Assert.AreEqual(expected, actual);
        }

        [TestMethod]
        public void RemovePositionality_Collection()
        {
            IEnumerable<string> list = new[]
                                       {
                                           "/Prestazione/ServizioEnergetico[1]/AnagraficaBeneficiario[1]/cognome[1]",
                                           "/Prestazione/ServizioEnergetico[1]/AnagraficaBeneficiario[1]/rag_soc[1]"
                                       };
            ICollection expected = new[]
                                   {
                                       "/Prestazione/ServizioEnergetico/AnagraficaBeneficiario/cognome",
                                       "/Prestazione/ServizioEnergetico/AnagraficaBeneficiario/rag_soc"
                                   };
            ICollection actual = XPathExtensions.RemovePositionality(list);
            CollectionAssert.AreEqual(expected, actual);
        }

        [TestMethod]
        public void AddNodeTest_Collection()
        {
            IEnumerable<string> list = new[]
                                       {
                                           "/Prestazione/ServizioEnergetico/AnagraficaBeneficiario/cognome",
                                           "/Prestazione/ServizioEnergetico/AnagraficaBeneficiario/rag_soc"
                                       };
            ICollection expected = new[]
                                   {
                                       "/Prestazione/ServizioEnergetico/AnagraficaBeneficiario/cognome/text()",
                                       "/Prestazione/ServizioEnergetico/AnagraficaBeneficiario/rag_soc/text()"
                                   };
            ICollection actual = XPathExtensions.AddNodeTest(list);
            CollectionAssert.AreEqual(expected, actual);
        }

        [TestMethod]
        public void RemoveNodeTest_Text()
        {
            const string XPATH = "/Prestazione/ServizioEnergetico[1]/AnagraficaBeneficiario[1]/cognome[1]/text()";
            const string EXPECTED_XPATH = "/Prestazione/ServizioEnergetico[1]/AnagraficaBeneficiario[1]/cognome[1]";

            string actual = XPathExtensions.RemoveNodeTest(XPATH);

            Assert.AreEqual(EXPECTED_XPATH, actual);
        }

        [TestMethod]
        public void CompactXPath()
        {
            const string XPATH = "/Prestazione/ServizioEnergetico[1]/AnagraficaBeneficiario[1]/cognome[1]/text()";
            const string EXPECTED_XPATH = "/Prestazione/ServizioEnergetico/AnagraficaBeneficiario/cognome";

            string actual = XPathExtensions.Compact(XPATH);

            Assert.AreEqual(EXPECTED_XPATH, actual);
        }

        [TestMethod]
        public void CompactXPath_Collection()
        {
            IEnumerable<string> list = new[]
                                       {
                                           "/Prestazione/ServizioEnergetico[1]/AnagraficaBeneficiario[1]/cognome[1]/text()",
                                           "/Prestazione/ServizioEnergetico[1]/AnagraficaBeneficiario/cognome[1]/comment()",
                                           "/Prestazione/ServizioEnergetico[1]/AnagraficaBeneficiario[1]/rag_soc[1]"
                                       };
            ICollection expected = new[]
                                   {
                                       "/Prestazione/ServizioEnergetico/AnagraficaBeneficiario/cognome",
                                       "/Prestazione/ServizioEnergetico/AnagraficaBeneficiario/cognome",
                                       "/Prestazione/ServizioEnergetico/AnagraficaBeneficiario/rag_soc"
                                   };
            ICollection actual = XPathExtensions.Compact(list);
            CollectionAssert.AreEqual(expected, actual);
        }

        [TestMethod]
        public void IsMatch1()
        {
            const string XPATH1 = "/Prestazione/ServizioEnergetico[1]/AnagraficaBeneficiario[1]/cognome";
            const string XPATH2 = "/Prestazione/ServizioEnergetico/AnagraficaBeneficiario/cognome[1]/text()";

            bool actual = XPathExtensions.IsMatch(XPATH1, XPATH2);

            Assert.IsTrue(actual);
        }

        [TestMethod]
        public void IsMatch2()
        {
            const string XPATH1 = "/Prestazione/ServizioEnergetico[1]/AnagraficaBeneficiario[1]/cognome";
            const string XPATH2 = "/prestazione/ServizioEnergetico/AnagraficaBeneficiario/cognome[1]/text()";

            bool actual = XPathExtensions.IsMatch(XPATH1, XPATH2, StringComparison.InvariantCulture);

            Assert.IsFalse(actual);
        }

        [TestMethod]
        public void IsMatch3()
        {
            const string XPATH1 = "/Prestazione/ServizioEnergetico[1]/AnagraficaBeneficiario[1]/cognome";
            const string XPATH2 = "/prestazione/ServizioEnergetico/AnagraficaBeneficiario/cognome[1]/text()";

            bool actual = XPathExtensions.IsMatch(XPATH1, XPATH2, StringComparison.InvariantCultureIgnoreCase);

            Assert.IsTrue(actual);
        }

        [TestMethod]
        public void IsMatchListTrue1()
        {
            XPathList list1 = new XPathList(new[]
                                            {
                                                "/Prestazione/@cod_servizio",
                                                "/Prestazione/@cod_flusso",
                                                "/Prestazione/IdentificativiRichiesta[1]/piva_utente[1]"
                                            });

            XPathList list2 = new XPathList(new[]
                                            {
                                                "/Prestazione/@cod_servizio",
                                                "/Prestazione/@cod_flusso",
                                                "/Prestazione/IdentificativiRichiesta[1]/piva_utente[1]"
                                            });

            bool actual = list1.IsMatch(list2);

            Assert.IsTrue(actual);
        }

        [TestMethod]
        public void IsMatchListTrue2()
        {
            XPathList list1 = new XPathList(new[]
                                            {
                                                "/Prestazione/@cod_servizio",
                                                "/Prestazione/@cod_flusso",
                                                "/Prestazione/IdentificativiRichiesta/piva_utente"
                                            });

            XPathList list2 = new XPathList(new[]
                                            {
                                                "/Prestazione/@cod_servizio",
                                                "/Prestazione/@cod_flusso",
                                                "/Prestazione/IdentificativiRichiesta[1]/piva_utente[1]"
                                            });

            bool actual = list1.IsMatch(list2);

            Assert.IsTrue(actual);
        }

        [TestMethod]
        public void IsMatchListFalse1()
        {
            XPathList list1 = new XPathList(new[]
                                            {
                                                "/Prestazione/@cod_servizio-----------",
                                                "/Prestazione/@cod_flusso",
                                                "/Prestazione/IdentificativiRichiesta[1]/piva_utente[1]"
                                            });

            XPathList list2 = new XPathList(new[]
                                            {
                                                "/Prestazione/@cod_servizio",
                                                "/Prestazione/@cod_flusso",
                                                "/Prestazione/IdentificativiRichiesta[1]/piva_utente[1]"
                                            });

            bool actual = list1.IsMatch(list2);

            Assert.IsFalse(actual);
        }
    }
}